<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台（PHP版）
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码，建议反馈是我们前进的动力
// | 开源版本可自由商用，可去除界面版权logo
// | gitee下载：https://gitee.com/likeshop_gitee/likeadmin
// | github下载：https://github.com/likeshop-github/likeadmin
// | 访问官网：https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------

namespace app\adminapi\logic\reimbursement;


use app\common\enum\user\UserTerminalEnum;
use app\common\model\reimbursement\ExpenseApplication;
use app\common\model\reimbursement\ExpenseOperationLog;
use app\common\logic\BaseLogic;
use app\common\model\user\User;
use think\facade\Db;


/**
 * ExpenseApplication逻辑
 * Class ExpenseApplicationLogic
 * @package app\adminapi\logic\reimbursement
 */
class ExpenseApplicationLogic extends BaseLogic
{
    /**
     * 获取当前登录管理员信息
     */
    private static function getAdminInfo()
    {
        $adminInfo = request()->adminInfo;
        if (empty($adminInfo)) {
            throw new \Exception('未获取到管理员信息');
        }
        $id = $adminInfo['id'] ?? $adminInfo['admin_id'] ?? null;
        $name = $adminInfo['name'] ?? $adminInfo['account'] ?? $adminInfo['username'] ?? '';
        if (!$id) {
            throw new \Exception('未获取到管理员ID');
        }
        return [
            'id' => $id,
            'name' => $name
        ];
    }

    /**
     * 记录操作日志
     * @param int $expenseId 报账ID
     * @param string $content 操作内容
     * @param int $operationType 操作类型
     */
    private static function recordOperation($expenseId, $content, $operationType)
    {
        $adminInfo = self::getAdminInfo();
        $log = new ExpenseOperationLog();
        $log->save([
            'expense_id' => $expenseId,
            'operator_id' => $adminInfo['id'],
            'operator_name' => $adminInfo['name'],
            'operation_type' => $operationType,
            'operation_content' => $content
        ]);
    }

    /**
     * 获取申请人下拉列表
     * @return array
     */
    public static function getApplicantsList():array
    {
        try{
            // 只查询未锁定的用户
            $users = User::where('is_disable', 0)
                ->field(['id', 'nickname as label', 'nickname as value'])
                ->select()
                ->toArray();
            return [
                'success' => true,
                'data' => $users
            ];
        } catch(\Exception $e){
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * @notes 添加报账记录
     * @param array $params
     * @return array
     */
    public static function add(array $params): array
    {
        Db::startTrans();
        try {
            // 获取用户信息
            $user = User::where('id', $params['applicant_id'])->find();
            if (!$user || $user->is_locked) {
                throw new \Exception('账户状态异常，无法提交申请');
            }
            // 获取费用类型
            $expenseType = \app\common\model\reimbursement\ExpenseType::where('id', $params['expense_type_id'])->find();
            if (!$expenseType) {
                throw new \Exception('费用类型不存在');
            }
            // 自动审批逻辑
            $autoApprovalAmount = 5000.00;
            $status = ($params['amount'] < $autoApprovalAmount) ? 3 : 1;
            // 创建申请记录
            $application = new ExpenseApplication();
            $result = $application->save([
                'applicant_id' => $params['applicant_id'],
                'expense_type_id' => $params['expense_type_id'],
                'amount' => $params['amount'],
                'description' => isset($params['description']) ? $params['description'] : '',
                'current_status' => $status
            ]);
            if ($result) {
            // 记录操作日志
                self::recordOperation(
                    $application->id,
                    "创建报账申请：{$expenseType->name}，金额：{$params['amount']}",
                    1
                );
                Db::commit();
                $data = $application->toArray();
                unset($data['update_time'], $data['id'], $data['delete_time']);
                return [
                    'success' => true,
                    'data' => $data
                ];
            } else {
                throw new \Exception('保存失败');
            }
        } catch (\Exception $e) {
            Db::rollback();
            self::setError($e->getMessage());
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * @notes 编辑报账记录
     * @param array $params
     * @return array
     */
    public static function edit(array $params): array
    {
        Db::startTrans();
        try {
            $application = ExpenseApplication::where('id', $params['id'])->findOrEmpty();
            if ($application->isEmpty()) {
                throw new \Exception('申请记录不存在');
            }

            // 更新数据（仅修改传递的字段）
            $updateData = [];
            $changes = [];

            // 费用类型
            if (isset($params['expense_type_id']) && $params['expense_type_id'] != $application->expense_type_id) {
                $expenseType = \app\common\model\reimbursement\ExpenseType::where('id', $params['expense_type_id'])->find();
                if (!$expenseType) {
                    throw new \Exception('费用类型不存在');
                }
                $oldType = \app\common\model\reimbursement\ExpenseType::where('id', $application->expense_type_id)->value('name');
                $updateData['expense_type_id'] = $params['expense_type_id'];
                $changes['expense_type'] = [
                    'old' => $oldType,
                    'new' => $expenseType->name
                ];
            }
            // 金额
            if (isset($params['amount']) && $params['amount'] != $application->amount) {
                $updateData['amount'] = $params['amount'];
                $changes['amount'] = [
                    'old' => $application->amount,
                    'new' => $params['amount']
                ];
            }
            // 描述
            if (isset($params['description']) && $params['description'] !== $application->description) {
                $updateData['description'] = $params['description'];
                $changes['description'] = [
                    'old' => $application->description,
                    'new' => $params['description']
                ];
            }

            if (!empty($updateData)) {
                $application->save($updateData);
                // 记录操作日志
                if (!empty($changes)) {
                    $changeDesc = [];
                    foreach ($changes as $field => $change) {
                        $changeDesc[] = $field . "由" . $change['old'] . "改为" . $change['new'];
                    }
                    self::recordOperation(
                        $application->id,
                        "修改报账申请：" . implode("，", $changeDesc),
                        2
                    );
                }
            Db::commit();
                return [
                    'success' => true,
                    'message' => '修改成功',
                    'data' => $changes
                ];
            }
            return [
                'success' => true,
                'message' => '无数据更新',
                'data' => []
            ];
        } catch (\Exception $e) {
            Db::rollback();
            self::setError($e->getMessage());
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * @notes 删除报账记录
     * @param array $params
     * @return array
     */
    public static function delete(array $params): array
    {
        Db::startTrans();
        try {
            $application = ExpenseApplication::find($params['id']);
            if (!$application) {
                throw new \Exception('申请记录不存在');
            }

            // 记录操作日志
            self::recordOperation(
                $application->id,
                "删除报账申请：{$application->expense_type}，金额：{$application->amount}",
                3
            );

            $result = ExpenseApplication::destroy($params['id']);
            
            if ($result) {
                Db::commit();
                return [
                    'success' => true,
                    'message' => '删除成功'
                ];
            }
            throw new \Exception('删除失败');
        } catch (\Exception $e) {
            Db::rollback();
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * @notes 审批报账申请
     * @param array $params
     * @return array
     */
    public static function approve(array $params): array
    {
        Db::startTrans();
        try {
            $application = ExpenseApplication::where('id', $params['id'])->findOrEmpty();
            if ($application->isEmpty()) {
                throw new \Exception('申请记录不存在');
            }

            if ($application->current_status != 1) {
                throw new \Exception('当前状态不可审批');
            }

            $adminInfo = self::getAdminInfo();

            // 更新状态和审批信息
            $updateData = [
                'current_status' => $params['approve_status'],
                'approve_remark' => $params['remark'] ?? '',
                'approve_time' => time(),
                'approve_admin_id' => $adminInfo['id']
            ];

            $result = $application->save($updateData);

            if ($result) {
                // 记录操作日志
                $operationContent = $params['approve_status'] == 3 ? 
                    "审批通过了申请" : "退回了申请";
                if (!empty($params['remark'])) {
                    $operationContent .= "，备注：{$params['remark']}";
                }

                self::recordOperation(
                    $application->id,
                    $operationContent,
                    4
                );

                Db::commit();
                return [
                    'success' => true,
                    'message' => $params['approve_status'] == 3 ? '审批通过成功' : '退回成功',
                    'data' => [
                        'id' => $application->id,
                        'current_status' => $params['approve_status'],
                        'approve_remark' => $application->approve_remark
                    ]
                ];
            } else {
                throw new \Exception('审批操作失败');
            }
        } catch (\Exception $e) {
            Db::rollback();
            self::setError($e->getMessage());
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * @notes 获取操作日志列表
     * @param int $expenseId
     * @return array
     */
    public static function getOperationLogs(int $expenseId): array
    {
        try {
            $logs = ExpenseOperationLog::where('expense_id', $expenseId)
                ->order('create_time', 'desc')
                ->select()
                ->toArray();

            return [
                'success' => true,
                'data' => $logs
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * 获取报账申请详情
     * @param array $params
     * @return array
     */
    public static function detail(array $params): array
    {
        try {
            $application = ExpenseApplication::findOrEmpty($params['id']);
            if ($application->isEmpty()) {
                throw new \Exception('申请记录不存在');
            }
            $data = $application->toArray();
            unset($data['delete_time'], $data['id']);
            return [
                'success' => true,
                'data' => $data
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }
}